info <- read.csv("../data/train_set/label.csv")
load("../output/fiducial_pt_list.Rdata")
library(readxl)
# A function to plot histogram of distribution of pairwise distance for each emotion
# input: emotion index, first point, second point, vertical or horizontal distance
# output: histogram of distance distribution
dist_histogram_by_emotion <- function(emotion_idx, pt1, pt2, vertical = T){
    indices <- info[info$emotion_idx == emotion_idx, 'Index']
    emotion <- as.character(info[info$emotion_idx == emotion_idx, 'emotion_cat'])[1]
    ver.dist <- function(idx){
        if(vertical){
        ver.loc <- fiducial_pt_list[[idx]][,2]
        }
        else{
        ver.loc <- fiducial_pt_list[[idx]][,1] 
        }
        pairwise_dist <- as.matrix(dist(ver.loc))
        ver.dist <- pairwise_dist[pt1,pt2]
    return(ver.dist)
}
    dist_distribution <- sapply(indices, ver.dist)
    #jpeg(paste(c('../output/hist', emotion_idx,"_", pt1, "_", pt2, '.jpg'), collapse = ''),
    #width = 500, height = 375)
    hist(dist_distribution, xlab = "distance", 
         main = paste(c(emotion, "distance between", pt1, "and", pt2),collapse = " ")) 
    abline(v = mean(dist_distribution))
    #dev.off()
}

# A function to generalize "dist_histogram_by_emotion" to all emotions 
dist_histogram <- function(pt1, pt2, vertical = T){
  lapply(1:22, dist_histogram_by_emotion, pt1, pt2, vertical)
}

#examples
dist_histogram(50,52)

[[1]]
NULL

[[2]]
NULL

[[3]]
NULL

[[4]]
NULL

[[5]]
NULL

[[6]]
NULL

[[7]]
NULL

[[8]]
NULL

[[9]]
NULL

[[10]]
NULL

[[11]]
NULL

[[12]]
NULL

[[13]]
NULL

[[14]]
NULL

[[15]]
NULL

[[16]]
NULL

[[17]]
NULL

[[18]]
NULL

[[19]]
NULL

[[20]]
NULL

[[21]]
NULL

[[22]]
NULL

dist_histogram(1,21)

[[1]]
NULL

[[2]]
NULL

[[3]]
NULL

[[4]]
NULL

[[5]]
NULL

[[6]]
NULL

[[7]]
NULL

[[8]]
NULL

[[9]]
NULL

[[10]]
NULL

[[11]]
NULL

[[12]]
NULL

[[13]]
NULL

[[14]]
NULL

[[15]]
NULL

[[16]]
NULL

[[17]]
NULL

[[18]]
NULL

[[19]]
NULL

[[20]]
NULL

[[21]]
NULL

[[22]]
NULL

library(EBImage)
# a function display fiducial points on images
# input: identity index
# output: all images associated with the identity with fiducial points marked
display_fid_pt <- function(identity){
    indices <- info[info$identity == identity, 'Index']
    emotions <- as.character(info[info$identity == identity, 'emotion_cat'])
    image.path_sub <- paste0(train_image_dir, sprintf("%04d", indices), ".jpg")
    Image_list_sub <- lapply(image.path_sub, EBImage::readImage)
    fiducial_pt_list_sub <- fiducial_pt_list[indices]

    display_single <- function(j){
        #jpeg(paste(c('../output/', identity,'_', j, '.jpg'), collapse = ''), width = 500, height = 375)
        display(Image(Image_list_sub[[j]], colormode = 'Color'), method="raster")
        text(x = 170, y = 50, label = emotions[j], cex = 1.5)
        add_point <- function(n){text(x = fiducial_pt_list_sub[[j]][n,1],
                                      y = fiducial_pt_list_sub[[j]][n,2],
                                      label = as.character(n), col = "white", cex = 0.8)}
        lapply(1:78,add_point)
        #dev.off() 
}

    lapply(1:length(indices), display_single) 
}

display_fid_pt(110)

[[1]]
[[1]][[1]]
NULL

[[1]][[2]]
NULL

[[1]][[3]]
NULL

[[1]][[4]]
NULL

[[1]][[5]]
NULL

[[1]][[6]]
NULL

[[1]][[7]]
NULL

[[1]][[8]]
NULL

[[1]][[9]]
NULL

[[1]][[10]]
NULL

[[1]][[11]]
NULL

[[1]][[12]]
NULL

[[1]][[13]]
NULL

[[1]][[14]]
NULL

[[1]][[15]]
NULL

[[1]][[16]]
NULL

[[1]][[17]]
NULL

[[1]][[18]]
NULL

[[1]][[19]]
NULL

[[1]][[20]]
NULL

[[1]][[21]]
NULL

[[1]][[22]]
NULL

[[1]][[23]]
NULL

[[1]][[24]]
NULL

[[1]][[25]]
NULL

[[1]][[26]]
NULL

[[1]][[27]]
NULL

[[1]][[28]]
NULL

[[1]][[29]]
NULL

[[1]][[30]]
NULL

[[1]][[31]]
NULL

[[1]][[32]]
NULL

[[1]][[33]]
NULL

[[1]][[34]]
NULL

[[1]][[35]]
NULL

[[1]][[36]]
NULL

[[1]][[37]]
NULL

[[1]][[38]]
NULL

[[1]][[39]]
NULL

[[1]][[40]]
NULL

[[1]][[41]]
NULL

[[1]][[42]]
NULL

[[1]][[43]]
NULL

[[1]][[44]]
NULL

[[1]][[45]]
NULL

[[1]][[46]]
NULL

[[1]][[47]]
NULL

[[1]][[48]]
NULL

[[1]][[49]]
NULL

[[1]][[50]]
NULL

[[1]][[51]]
NULL

[[1]][[52]]
NULL

[[1]][[53]]
NULL

[[1]][[54]]
NULL

[[1]][[55]]
NULL

[[1]][[56]]
NULL

[[1]][[57]]
NULL

[[1]][[58]]
NULL

[[1]][[59]]
NULL

[[1]][[60]]
NULL

[[1]][[61]]
NULL

[[1]][[62]]
NULL

[[1]][[63]]
NULL

[[1]][[64]]
NULL

[[1]][[65]]
NULL

[[1]][[66]]
NULL

[[1]][[67]]
NULL

[[1]][[68]]
NULL

[[1]][[69]]
NULL

[[1]][[70]]
NULL

[[1]][[71]]
NULL

[[1]][[72]]
NULL

[[1]][[73]]
NULL

[[1]][[74]]
NULL

[[1]][[75]]
NULL

[[1]][[76]]
NULL

[[1]][[77]]
NULL

[[1]][[78]]
NULL


[[2]]
[[2]][[1]]
NULL

[[2]][[2]]
NULL

[[2]][[3]]
NULL

[[2]][[4]]
NULL

[[2]][[5]]
NULL

[[2]][[6]]
NULL

[[2]][[7]]
NULL

[[2]][[8]]
NULL

[[2]][[9]]
NULL

[[2]][[10]]
NULL

[[2]][[11]]
NULL

[[2]][[12]]
NULL

[[2]][[13]]
NULL

[[2]][[14]]
NULL

[[2]][[15]]
NULL

[[2]][[16]]
NULL

[[2]][[17]]
NULL

[[2]][[18]]
NULL

[[2]][[19]]
NULL

[[2]][[20]]
NULL

[[2]][[21]]
NULL

[[2]][[22]]
NULL

[[2]][[23]]
NULL

[[2]][[24]]
NULL

[[2]][[25]]
NULL

[[2]][[26]]
NULL

[[2]][[27]]
NULL

[[2]][[28]]
NULL

[[2]][[29]]
NULL

[[2]][[30]]
NULL

[[2]][[31]]
NULL

[[2]][[32]]
NULL

[[2]][[33]]
NULL

[[2]][[34]]
NULL

[[2]][[35]]
NULL

[[2]][[36]]
NULL

[[2]][[37]]
NULL

[[2]][[38]]
NULL

[[2]][[39]]
NULL

[[2]][[40]]
NULL

[[2]][[41]]
NULL

[[2]][[42]]
NULL

[[2]][[43]]
NULL

[[2]][[44]]
NULL

[[2]][[45]]
NULL

[[2]][[46]]
NULL

[[2]][[47]]
NULL

[[2]][[48]]
NULL

[[2]][[49]]
NULL

[[2]][[50]]
NULL

[[2]][[51]]
NULL

[[2]][[52]]
NULL

[[2]][[53]]
NULL

[[2]][[54]]
NULL

[[2]][[55]]
NULL

[[2]][[56]]
NULL

[[2]][[57]]
NULL

[[2]][[58]]
NULL

[[2]][[59]]
NULL

[[2]][[60]]
NULL

[[2]][[61]]
NULL

[[2]][[62]]
NULL

[[2]][[63]]
NULL

[[2]][[64]]
NULL

[[2]][[65]]
NULL

[[2]][[66]]
NULL

[[2]][[67]]
NULL

[[2]][[68]]
NULL

[[2]][[69]]
NULL

[[2]][[70]]
NULL

[[2]][[71]]
NULL

[[2]][[72]]
NULL

[[2]][[73]]
NULL

[[2]][[74]]
NULL

[[2]][[75]]
NULL

[[2]][[76]]
NULL

[[2]][[77]]
NULL

[[2]][[78]]
NULL


[[3]]
[[3]][[1]]
NULL

[[3]][[2]]
NULL

[[3]][[3]]
NULL

[[3]][[4]]
NULL

[[3]][[5]]
NULL

[[3]][[6]]
NULL

[[3]][[7]]
NULL

[[3]][[8]]
NULL

[[3]][[9]]
NULL

[[3]][[10]]
NULL

[[3]][[11]]
NULL

[[3]][[12]]
NULL

[[3]][[13]]
NULL

[[3]][[14]]
NULL

[[3]][[15]]
NULL

[[3]][[16]]
NULL

[[3]][[17]]
NULL

[[3]][[18]]
NULL

[[3]][[19]]
NULL

[[3]][[20]]
NULL

[[3]][[21]]
NULL

[[3]][[22]]
NULL

[[3]][[23]]
NULL

[[3]][[24]]
NULL

[[3]][[25]]
NULL

[[3]][[26]]
NULL

[[3]][[27]]
NULL

[[3]][[28]]
NULL

[[3]][[29]]
NULL

[[3]][[30]]
NULL

[[3]][[31]]
NULL

[[3]][[32]]
NULL

[[3]][[33]]
NULL

[[3]][[34]]
NULL

[[3]][[35]]
NULL

[[3]][[36]]
NULL

[[3]][[37]]
NULL

[[3]][[38]]
NULL

[[3]][[39]]
NULL

[[3]][[40]]
NULL

[[3]][[41]]
NULL

[[3]][[42]]
NULL

[[3]][[43]]
NULL

[[3]][[44]]
NULL

[[3]][[45]]
NULL

[[3]][[46]]
NULL

[[3]][[47]]
NULL

[[3]][[48]]
NULL

[[3]][[49]]
NULL

[[3]][[50]]
NULL

[[3]][[51]]
NULL

[[3]][[52]]
NULL

[[3]][[53]]
NULL

[[3]][[54]]
NULL

[[3]][[55]]
NULL

[[3]][[56]]
NULL

[[3]][[57]]
NULL

[[3]][[58]]
NULL

[[3]][[59]]
NULL

[[3]][[60]]
NULL

[[3]][[61]]
NULL

[[3]][[62]]
NULL

[[3]][[63]]
NULL

[[3]][[64]]
NULL

[[3]][[65]]
NULL

[[3]][[66]]
NULL

[[3]][[67]]
NULL

[[3]][[68]]
NULL

[[3]][[69]]
NULL

[[3]][[70]]
NULL

[[3]][[71]]
NULL

[[3]][[72]]
NULL

[[3]][[73]]
NULL

[[3]][[74]]
NULL

[[3]][[75]]
NULL

[[3]][[76]]
NULL

[[3]][[77]]
NULL

[[3]][[78]]
NULL


[[4]]
[[4]][[1]]
NULL

[[4]][[2]]
NULL

[[4]][[3]]
NULL

[[4]][[4]]
NULL

[[4]][[5]]
NULL

[[4]][[6]]
NULL

[[4]][[7]]
NULL

[[4]][[8]]
NULL

[[4]][[9]]
NULL

[[4]][[10]]
NULL

[[4]][[11]]
NULL

[[4]][[12]]
NULL

[[4]][[13]]
NULL

[[4]][[14]]
NULL

[[4]][[15]]
NULL

[[4]][[16]]
NULL

[[4]][[17]]
NULL

[[4]][[18]]
NULL

[[4]][[19]]
NULL

[[4]][[20]]
NULL

[[4]][[21]]
NULL

[[4]][[22]]
NULL

[[4]][[23]]
NULL

[[4]][[24]]
NULL

[[4]][[25]]
NULL

[[4]][[26]]
NULL

[[4]][[27]]
NULL

[[4]][[28]]
NULL

[[4]][[29]]
NULL

[[4]][[30]]
NULL

[[4]][[31]]
NULL

[[4]][[32]]
NULL

[[4]][[33]]
NULL

[[4]][[34]]
NULL

[[4]][[35]]
NULL

[[4]][[36]]
NULL

[[4]][[37]]
NULL

[[4]][[38]]
NULL

[[4]][[39]]
NULL

[[4]][[40]]
NULL

[[4]][[41]]
NULL

[[4]][[42]]
NULL

[[4]][[43]]
NULL

[[4]][[44]]
NULL

[[4]][[45]]
NULL

[[4]][[46]]
NULL

[[4]][[47]]
NULL

[[4]][[48]]
NULL

[[4]][[49]]
NULL

[[4]][[50]]
NULL

[[4]][[51]]
NULL

[[4]][[52]]
NULL

[[4]][[53]]
NULL

[[4]][[54]]
NULL

[[4]][[55]]
NULL

[[4]][[56]]
NULL

[[4]][[57]]
NULL

[[4]][[58]]
NULL

[[4]][[59]]
NULL

[[4]][[60]]
NULL

[[4]][[61]]
NULL

[[4]][[62]]
NULL

[[4]][[63]]
NULL

[[4]][[64]]
NULL

[[4]][[65]]
NULL

[[4]][[66]]
NULL

[[4]][[67]]
NULL

[[4]][[68]]
NULL

[[4]][[69]]
NULL

[[4]][[70]]
NULL

[[4]][[71]]
NULL

[[4]][[72]]
NULL

[[4]][[73]]
NULL

[[4]][[74]]
NULL

[[4]][[75]]
NULL

[[4]][[76]]
NULL

[[4]][[77]]
NULL

[[4]][[78]]
NULL


[[5]]
[[5]][[1]]
NULL

[[5]][[2]]
NULL

[[5]][[3]]
NULL

[[5]][[4]]
NULL

[[5]][[5]]
NULL

[[5]][[6]]
NULL

[[5]][[7]]
NULL

[[5]][[8]]
NULL

[[5]][[9]]
NULL

[[5]][[10]]
NULL

[[5]][[11]]
NULL

[[5]][[12]]
NULL

[[5]][[13]]
NULL

[[5]][[14]]
NULL

[[5]][[15]]
NULL

[[5]][[16]]
NULL

[[5]][[17]]
NULL

[[5]][[18]]
NULL

[[5]][[19]]
NULL

[[5]][[20]]
NULL

[[5]][[21]]
NULL

[[5]][[22]]
NULL

[[5]][[23]]
NULL

[[5]][[24]]
NULL

[[5]][[25]]
NULL

[[5]][[26]]
NULL

[[5]][[27]]
NULL

[[5]][[28]]
NULL

[[5]][[29]]
NULL

[[5]][[30]]
NULL

[[5]][[31]]
NULL

[[5]][[32]]
NULL

[[5]][[33]]
NULL

[[5]][[34]]
NULL

[[5]][[35]]
NULL

[[5]][[36]]
NULL

[[5]][[37]]
NULL

[[5]][[38]]
NULL

[[5]][[39]]
NULL

[[5]][[40]]
NULL

[[5]][[41]]
NULL

[[5]][[42]]
NULL

[[5]][[43]]
NULL

[[5]][[44]]
NULL

[[5]][[45]]
NULL

[[5]][[46]]
NULL

[[5]][[47]]
NULL

[[5]][[48]]
NULL

[[5]][[49]]
NULL

[[5]][[50]]
NULL

[[5]][[51]]
NULL

[[5]][[52]]
NULL

[[5]][[53]]
NULL

[[5]][[54]]
NULL

[[5]][[55]]
NULL

[[5]][[56]]
NULL

[[5]][[57]]
NULL

[[5]][[58]]
NULL

[[5]][[59]]
NULL

[[5]][[60]]
NULL

[[5]][[61]]
NULL

[[5]][[62]]
NULL

[[5]][[63]]
NULL

[[5]][[64]]
NULL

[[5]][[65]]
NULL

[[5]][[66]]
NULL

[[5]][[67]]
NULL

[[5]][[68]]
NULL

[[5]][[69]]
NULL

[[5]][[70]]
NULL

[[5]][[71]]
NULL

[[5]][[72]]
NULL

[[5]][[73]]
NULL

[[5]][[74]]
NULL

[[5]][[75]]
NULL

[[5]][[76]]
NULL

[[5]][[77]]
NULL

[[5]][[78]]
NULL


[[6]]
[[6]][[1]]
NULL

[[6]][[2]]
NULL

[[6]][[3]]
NULL

[[6]][[4]]
NULL

[[6]][[5]]
NULL

[[6]][[6]]
NULL

[[6]][[7]]
NULL

[[6]][[8]]
NULL

[[6]][[9]]
NULL

[[6]][[10]]
NULL

[[6]][[11]]
NULL

[[6]][[12]]
NULL

[[6]][[13]]
NULL

[[6]][[14]]
NULL

[[6]][[15]]
NULL

[[6]][[16]]
NULL

[[6]][[17]]
NULL

[[6]][[18]]
NULL

[[6]][[19]]
NULL

[[6]][[20]]
NULL

[[6]][[21]]
NULL

[[6]][[22]]
NULL

[[6]][[23]]
NULL

[[6]][[24]]
NULL

[[6]][[25]]
NULL

[[6]][[26]]
NULL

[[6]][[27]]
NULL

[[6]][[28]]
NULL

[[6]][[29]]
NULL

[[6]][[30]]
NULL

[[6]][[31]]
NULL

[[6]][[32]]
NULL

[[6]][[33]]
NULL

[[6]][[34]]
NULL

[[6]][[35]]
NULL

[[6]][[36]]
NULL

[[6]][[37]]
NULL

[[6]][[38]]
NULL

[[6]][[39]]
NULL

[[6]][[40]]
NULL

[[6]][[41]]
NULL

[[6]][[42]]
NULL

[[6]][[43]]
NULL

[[6]][[44]]
NULL

[[6]][[45]]
NULL

[[6]][[46]]
NULL

[[6]][[47]]
NULL

[[6]][[48]]
NULL

[[6]][[49]]
NULL

[[6]][[50]]
NULL

[[6]][[51]]
NULL

[[6]][[52]]
NULL

[[6]][[53]]
NULL

[[6]][[54]]
NULL

[[6]][[55]]
NULL

[[6]][[56]]
NULL

[[6]][[57]]
NULL

[[6]][[58]]
NULL

[[6]][[59]]
NULL

[[6]][[60]]
NULL

[[6]][[61]]
NULL

[[6]][[62]]
NULL

[[6]][[63]]
NULL

[[6]][[64]]
NULL

[[6]][[65]]
NULL

[[6]][[66]]
NA

LS0tDQp0aXRsZTogIkZ1bmN0aW9ucyB0byBHZW5lcmF0ZSBGaWd1cmUgMSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBpbmZvX3ByaW50OiBwYWdlZA0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQogIHBpbmZvX2RvY3VtZW50OiBkZWZhdWx0DQogIHdvcmRfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQpgYGB7cn0NCmluZm8gPC0gcmVhZC5jc3YoIi4uL2RhdGEvdHJhaW5fc2V0L2xhYmVsLmNzdiIpDQpsb2FkKCIuLi9vdXRwdXQvZmlkdWNpYWxfcHRfbGlzdC5SZGF0YSIpDQpsaWJyYXJ5KHJlYWR4bCkNCiMgQSBmdW5jdGlvbiB0byBwbG90IGhpc3RvZ3JhbSBvZiBkaXN0cmlidXRpb24gb2YgcGFpcndpc2UgZGlzdGFuY2UgZm9yIGVhY2ggZW1vdGlvbg0KIyBpbnB1dDogZW1vdGlvbiBpbmRleCwgZmlyc3QgcG9pbnQsIHNlY29uZCBwb2ludCwgdmVydGljYWwgb3IgaG9yaXpvbnRhbCBkaXN0YW5jZQ0KIyBvdXRwdXQ6IGhpc3RvZ3JhbSBvZiBkaXN0YW5jZSBkaXN0cmlidXRpb24NCmRpc3RfaGlzdG9ncmFtX2J5X2Vtb3Rpb24gPC0gZnVuY3Rpb24oZW1vdGlvbl9pZHgsIHB0MSwgcHQyLCB2ZXJ0aWNhbCA9IFQpew0KICAgIGluZGljZXMgPC0gaW5mb1tpbmZvJGVtb3Rpb25faWR4ID09IGVtb3Rpb25faWR4LCAnSW5kZXgnXQ0KICAgIGVtb3Rpb24gPC0gYXMuY2hhcmFjdGVyKGluZm9baW5mbyRlbW90aW9uX2lkeCA9PSBlbW90aW9uX2lkeCwgJ2Vtb3Rpb25fY2F0J10pWzFdDQogICAgdmVyLmRpc3QgPC0gZnVuY3Rpb24oaWR4KXsNCiAgICAgICAgaWYodmVydGljYWwpew0KICAgICAgICB2ZXIubG9jIDwtIGZpZHVjaWFsX3B0X2xpc3RbW2lkeF1dWywyXQ0KICAgICAgICB9DQogICAgICAgIGVsc2V7DQogICAgICAgIHZlci5sb2MgPC0gZmlkdWNpYWxfcHRfbGlzdFtbaWR4XV1bLDFdIA0KICAgICAgICB9DQogICAgICAgIHBhaXJ3aXNlX2Rpc3QgPC0gYXMubWF0cml4KGRpc3QodmVyLmxvYykpDQogICAgICAgIHZlci5kaXN0IDwtIHBhaXJ3aXNlX2Rpc3RbcHQxLHB0Ml0NCiAgICByZXR1cm4odmVyLmRpc3QpDQp9DQogICAgZGlzdF9kaXN0cmlidXRpb24gPC0gc2FwcGx5KGluZGljZXMsIHZlci5kaXN0KQ0KICAgICNqcGVnKHBhc3RlKGMoJy4uL291dHB1dC9oaXN0JywgZW1vdGlvbl9pZHgsIl8iLCBwdDEsICJfIiwgcHQyLCAnLmpwZycpLCBjb2xsYXBzZSA9ICcnKSwNCiAgICAjd2lkdGggPSA1MDAsIGhlaWdodCA9IDM3NSkNCiAgICBoaXN0KGRpc3RfZGlzdHJpYnV0aW9uLCB4bGFiID0gImRpc3RhbmNlIiwgDQogICAgICAgICBtYWluID0gcGFzdGUoYyhlbW90aW9uLCAiZGlzdGFuY2UgYmV0d2VlbiIsIHB0MSwgImFuZCIsIHB0MiksY29sbGFwc2UgPSAiICIpKSANCiAgICBhYmxpbmUodiA9IG1lYW4oZGlzdF9kaXN0cmlidXRpb24pKQ0KICAgICNkZXYub2ZmKCkNCn0NCg0KIyBBIGZ1bmN0aW9uIHRvIGdlbmVyYWxpemUgImRpc3RfaGlzdG9ncmFtX2J5X2Vtb3Rpb24iIHRvIGFsbCBlbW90aW9ucyANCmRpc3RfaGlzdG9ncmFtIDwtIGZ1bmN0aW9uKHB0MSwgcHQyLCB2ZXJ0aWNhbCA9IFQpew0KICBsYXBwbHkoMToyMiwgZGlzdF9oaXN0b2dyYW1fYnlfZW1vdGlvbiwgcHQxLCBwdDIsIHZlcnRpY2FsKQ0KfQ0KDQojZXhhbXBsZXMNCmRpc3RfaGlzdG9ncmFtKDUwLDUyKQ0KZGlzdF9oaXN0b2dyYW0oMSwyMSkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoRUJJbWFnZSkNCiMgYSBmdW5jdGlvbiBkaXNwbGF5IGZpZHVjaWFsIHBvaW50cyBvbiBpbWFnZXMNCiMgaW5wdXQ6IGlkZW50aXR5IGluZGV4DQojIG91dHB1dDogYWxsIGltYWdlcyBhc3NvY2lhdGVkIHdpdGggdGhlIGlkZW50aXR5IHdpdGggZmlkdWNpYWwgcG9pbnRzIG1hcmtlZA0KZGlzcGxheV9maWRfcHQgPC0gZnVuY3Rpb24oaWRlbnRpdHkpew0KICAgIGluZGljZXMgPC0gaW5mb1tpbmZvJGlkZW50aXR5ID09IGlkZW50aXR5LCAnSW5kZXgnXQ0KICAgIGVtb3Rpb25zIDwtIGFzLmNoYXJhY3RlcihpbmZvW2luZm8kaWRlbnRpdHkgPT0gaWRlbnRpdHksICdlbW90aW9uX2NhdCddKQ0KICAgIGltYWdlLnBhdGhfc3ViIDwtIHBhc3RlMCh0cmFpbl9pbWFnZV9kaXIsIHNwcmludGYoIiUwNGQiLCBpbmRpY2VzKSwgIi5qcGciKQ0KICAgIEltYWdlX2xpc3Rfc3ViIDwtIGxhcHBseShpbWFnZS5wYXRoX3N1YiwgRUJJbWFnZTo6cmVhZEltYWdlKQ0KICAgIGZpZHVjaWFsX3B0X2xpc3Rfc3ViIDwtIGZpZHVjaWFsX3B0X2xpc3RbaW5kaWNlc10NCg0KICAgIGRpc3BsYXlfc2luZ2xlIDwtIGZ1bmN0aW9uKGopew0KICAgICAgICAjanBlZyhwYXN0ZShjKCcuLi9vdXRwdXQvJywgaWRlbnRpdHksJ18nLCBqLCAnLmpwZycpLCBjb2xsYXBzZSA9ICcnKSwgd2lkdGggPSA1MDAsIGhlaWdodCA9IDM3NSkNCiAgICAgICAgZGlzcGxheShJbWFnZShJbWFnZV9saXN0X3N1Yltbal1dLCBjb2xvcm1vZGUgPSAnQ29sb3InKSwgbWV0aG9kPSJyYXN0ZXIiKQ0KICAgICAgICB0ZXh0KHggPSAxNzAsIHkgPSA1MCwgbGFiZWwgPSBlbW90aW9uc1tqXSwgY2V4ID0gMS41KQ0KICAgICAgICBhZGRfcG9pbnQgPC0gZnVuY3Rpb24obil7dGV4dCh4ID0gZmlkdWNpYWxfcHRfbGlzdF9zdWJbW2pdXVtuLDFdLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gZmlkdWNpYWxfcHRfbGlzdF9zdWJbW2pdXVtuLDJdLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IGFzLmNoYXJhY3RlcihuKSwgY29sID0gIndoaXRlIiwgY2V4ID0gMC44KX0NCiAgICAgICAgbGFwcGx5KDE6NzgsYWRkX3BvaW50KQ0KICAgICAgICAjZGV2Lm9mZigpIA0KfQ0KDQogICAgbGFwcGx5KDE6bGVuZ3RoKGluZGljZXMpLCBkaXNwbGF5X3NpbmdsZSkgDQp9DQoNCmRpc3BsYXlfZmlkX3B0KDM4NikNCg0KYGBgDQoNCg==